package com.gnizr.feed ;

import com.gnizr.feed.FeedItem ;

import java.util.Collections ;

import java.sql.CallableStatement ;
import java.sql.Connection ;
import java.sql.PreparedStatement ;
import java.sql.ResultSet ;
import java.sql.SQLException ;
import java.sql.Timestamp ;
import java.sql.Types ;
import java.util.ArrayList ;
import java.util.Date ;
import java.util.List ;

import javax.sql.DataSource ;

import org.apache.log4j.Logger ;

import com.gnizr.db.dao.Bookmark ;
import com.gnizr.db.dao.DBUtil ;
import com.gnizr.db.dao.DaoResult ;
import com.gnizr.db.dao.Link ;
import com.gnizr.db.dao.Tag ;
import com.gnizr.db.dao.User ;
import com.gnizr.db.dao.link.LinkDBDao ;
import com.gnizr.db.dao.user.UserDBDao ;
import com.gnizr.db.vocab.BookmarkSchema ;

public class FeedDBDao implements FeedDao
{
	/**
	 * 
	 */
	private static final long serialVersionUID = -4420733276360895659L ;

	private static final Logger logger = Logger.getLogger(FeedDBDao.class.getName());
	
	private DataSource dataSource ;
	
	public FeedDBDao(DataSource ds){
		this.dataSource = ds ;
	}
    
    public DaoResult<FeedItem> fetchAllFeeds(Timestamp startTime, Timestamp stopTime)
    {
        DaoResult<FeedItem> result = null;
		List<FeedItem> items = new ArrayList<FeedItem>();

        items.addAll(fetchFeed(BOOKMARKS, startTime, stopTime).getResult()) ;
        items.addAll(fetchFeed(FOLDERS, startTime, stopTime).getResult()) ;
        items.addAll(fetchFeed(SUBSCRIPTIONS, startTime, stopTime).getResult()) ;
        items.addAll(fetchFeed(USERS, startTime, stopTime).getResult()) ;
        items.addAll(fetchFeed(TAGS, startTime, stopTime).getResult()) ;
		
		Collections.sort(items) ;
		Collections.reverse(items) ;
		
		result = new DaoResult<FeedItem>(items,items.size());
		return result ;
    }

	public DaoResult<FeedItem> fetchFeed(int type, Timestamp startTime, Timestamp stopTime) {
		logger.debug(formData[type] + ", input: startTime="+startTime 
				+",stopTime="+stopTime);
		Connection conn = null;
		CallableStatement cStmt = null;
		DaoResult<FeedItem> result = null;
		List<FeedItem> items = new ArrayList<FeedItem>();
		try {
			conn = dataSource.getConnection();
			cStmt = conn.prepareCall("call " +
			    formData[type] + "(?,?,?,?);");

			cStmt.setTimestamp(1, startTime);
			cStmt.setTimestamp(2, stopTime);
			cStmt.registerOutParameter(3, Types.INTEGER);
			cStmt.setInt(4, DESCENDING);
			ResultSet rs = cStmt.executeQuery();
			int size = cStmt.getInt(3);
			if(size < 0){
				size = 0;
			}
			while(rs.next()){
				FeedItem tmp = createFeedItem(rs);
				logger.debug("found item="+tmp);
				items.add(tmp);
			}
			result = new DaoResult<FeedItem>(items,size);
		} catch (SQLException e) {
			logger.fatal(e);
		}finally{
			try {
				DBUtil.cleanup(conn, cStmt);
			} catch (SQLException e) {
				logger.fatal(e);
			}
		}
		return result;
	}

	public static FeedItem createFeedItem(ResultSet rs) throws SQLException {
		if(rs == null) return null ;

		FeedItem item = new FeedItem() ;

        item.setId(rs.getInt("id")) ;
        item.setTitle(rs.getString("title")) ;
        item.setCreatedOn(rs.getTimestamp("createdOn")) ;
        item.setLastUpdated(rs.getTimestamp("lastUpdated")) ;
        item.setUserName(rs.getString("username")) ;
        item.setFullName(rs.getString("fullname")) ;
        item.setLink(rs.getString("link")) ;
        item.setType(rs.getInt("type")) ;

		return item ;
	}
}
